package com.example.common.tools

import io.reactivex.Observable
import io.reactivex.Observer
import io.reactivex.android.schedulers.AndroidSchedulers
import io.reactivex.disposables.Disposable
import io.reactivex.schedulers.Schedulers
import java.util.concurrent.TimeUnit


class TimerUtils {

    companion object {
        val instance = TimerUtils()

        abstract class TimerObserver<T> : Observer<T> {

            override fun onSubscribe(p0: Disposable) {
            }

            override fun onComplete() {
            }

            override fun onNext(p0: T) {
            }

            override fun onError(p0: Throwable) {
            }

        }

        interface OnTimeListener {
            fun onSubscribe(d: Disposable)
            fun onSeconds(seconds: String)
            fun onMinute(minute: String)
            fun onHours(hours: String)
            fun onDay(day: Int)
        }
    }

    //验证码计时器
    fun getTimer(count: Long): Observable<Long> {
        return Observable.interval(0, 1, TimeUnit.SECONDS)
            .take(count)
            .map {
                return@map count - it
            }
            .subscribeOn(Schedulers.io())
            .observeOn(AndroidSchedulers.mainThread())
    }


    //计时器
    fun timer(count: Long, timerListener: TimerObserver<Long>) {
        Observable.interval(0, 1, TimeUnit.SECONDS)
            .take(count)
            .map {
                return@map count - it
            }
            .subscribeOn(Schedulers.io())
            .observeOn(AndroidSchedulers.mainThread())
            .subscribe(timerListener)
    }


    //计时器
    fun timer(count: Long,timeUnit: TimeUnit) :Observable<Long>{
        return Observable.interval(0, 1, timeUnit)
            .take(count)
            .map {
                return@map count - it
            }
            .subscribeOn(Schedulers.io())
    }

    //计时器
    fun timer(timerListener: TimerObserver<Long>) {
        Observable.interval(0, 1, TimeUnit.SECONDS)
            .subscribeOn(Schedulers.io())
            .observeOn(AndroidSchedulers.mainThread())
            .subscribe(timerListener)
    }

    //延迟发送
    fun delay(millisSecond: Long): Observable<Long> {
        return Observable.timer(millisSecond, TimeUnit.MILLISECONDS)
            .observeOn(AndroidSchedulers.mainThread())
    }

    //秒表
    fun secondsWatch(listener: OnTimeListener) {
        var currentSeconds = 0
        var currentDay = 0
        Observable.interval(0, 1, TimeUnit.SECONDS)
            .subscribeOn(Schedulers.io())
            .observeOn(AndroidSchedulers.mainThread())
            .subscribe(object : Observer<Long> {
                override fun onComplete() {
                }

                override fun onSubscribe(d: Disposable) {
                    listener.onSubscribe(d)
                }

                override fun onNext(t: Long) {

                    //计算分钟
                    var minute = Math.floor((currentSeconds  / 60).toDouble())
                    val seconds = currentSeconds % 60
                    //计算小时
                    var hours = Math.floor(minute / 60)
                    if (minute > 59) {
                        minute %= 60
                    }
                    if (hours > 23) {
                        currentDay = Math.floor(hours / 24).toInt()
                        listener.onDay(currentDay)
                        hours %= 24
                    }
                    if (seconds < 10) {
                        listener.onSeconds("0$seconds")
                    } else {
                        listener.onSeconds("$seconds")
                    }
                    if (minute < 10) {
                        listener.onMinute("0${minute.toInt()}")
                    } else {
                        listener.onMinute("${minute.toInt()}")
                    }
                    if (hours < 10) {
                        listener.onHours("0${hours.toInt()}")
                    } else {
                        listener.onHours("${hours.toInt()}")
                    }
                    currentSeconds++
                }
                override fun onError(e: Throwable) {
                }

            })
    }

    //秒表计时器
    var currentSeconds = 0
    var currentDay = 0
    fun stopwatch(
        startSeconds: OnTimeListener ,
        startMinute: Int,
        startHours: Int,
        listener: OnTimeListener
    ) {

        Observable.interval(0, 1, TimeUnit.SECONDS)
            .subscribeOn(Schedulers.io())
            .observeOn(AndroidSchedulers.mainThread())
            .subscribe(object : Observer<Long> {
                override fun onComplete() {
                }

                override fun onSubscribe(d: Disposable) {
                    listener.onSubscribe(d)
                }

                override fun onNext(t: Long) {
                    var firstSeconds = startMinute * 60
                    var firstMinute = startHours * 60
                    //计算分钟
                    var minute = Math.floor(((currentSeconds + firstSeconds) / 60).toDouble())
                    val seconds = currentSeconds % 60
                    //计算小时
                    var hours = Math.floor((minute + firstMinute) / 60)
                    if (minute > 59) {
                        minute %= 60
                    }
                    if (hours > 23) {
                        currentDay = Math.floor(hours / 24).toInt()
                        listener.onDay(currentDay)
                        hours %= 24
                    }
                    if (seconds < 10) {
                        listener.onSeconds("0$seconds")
                    } else {
                        listener.onSeconds("$seconds")
                    }
                    if (minute < 10) {
                        listener.onMinute("0${minute.toInt()}")
                    } else {
                        listener.onMinute("${minute.toInt()}")
                    }
                    if (hours < 10) {
                        listener.onHours("0${hours.toInt()}")
                    } else {
                        listener.onHours("${hours.toInt()}")
                    }
                    currentSeconds++
                }

                override fun onError(e: Throwable) {
                }

            })
    }

}

